import { _decorator, Camera, Collider, Component, director, error, EventTouch, geometry, Node, physics, PhysicsSystem, sys, v3, Vec2, Vec3, view } from 'cc';
import { EventManager, MyEvent } from './EventManager';
import { Rotate } from './Rotate';
import { BoxController } from './BoxController';
import { WeaponPart } from './WeaponPart';
import { Group, PartPos } from './GameConstant';
import { Weapon } from './Weapon';
import { BoxManager } from './BoxManager';
import { AudioManager, Audios } from '../AshFramework/Managers/AudioManager';
const { ccclass, property } = _decorator;

@ccclass('TouchController')
export class TouchController extends Component {

    @property(Camera)
    Camera3D: Camera = null;

    Target: Node = null;
    PartPos: Vec3 = v3(0);

    Target2: Node = null;

    protected onLoad(): void {
        PhysicsSystem.instance.enable = true;

    }

    protected start(): void {
        this.node.on(Node.EventType.TOUCH_START, this.onTouchStart, this);
        this.node.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
        this.node.on(Node.EventType.TOUCH_END, this.onTouchEnd, this);
        this.node.on(Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this);
    }

    onTouchStart(event: EventTouch) {
        let ray = new geometry.Ray();
        this.Camera3D.screenPointToRay(event.getLocationX(), event.getLocationY(), ray);
        const mask = 0xffffffff;
        const maxDistance = 10000000;
        const queryTrigger = true;
        // let x: string = "";
        if (PhysicsSystem.instance.raycast(ray, mask, maxDistance, queryTrigger)) {
            const results = PhysicsSystem.instance.raycastResults;
            results.sort((a, b) => { return a.distance > b.distance ? 1 : -1 })

            this.Target = results[0].collider.node;

            if (results[0].collider.getGroup() == Group.Weapon) {
                AudioManager.PlaySound(Audios.PartClick);
                this.Target.getComponent(Rotate).click();
            } else if (results[0].collider.getGroup() == Group.WeaponPart) {
                AudioManager.PlaySound(Audios.PartClick);
                this.PartPos = this.Target.getPosition().clone();
            }
        }

    }

    onTouchMove(event: EventTouch) {
        // if (this.Target && this.Target.name == "手枪") {
        if (this.Target && this.Target.getComponent(Collider).getGroup() == Group.Weapon) {
            const prePosi = event.getPreviousLocation();
            const currentMousePosition = event.getLocation()
            const delta = currentMousePosition.subtract(prePosi);
            EventManager.Scene.emit(MyEvent.ROTATE, delta);
        } else if (this.Target && this.Target.getComponent(Collider).getGroup() == Group.WeaponPart) {
            let ray = new geometry.Ray();
            this.Camera3D.screenPointToRay(event.getLocationX(), event.getLocationY(), ray);
            const mask = 0xffffffff;
            const maxDistance = 10000000;
            const queryTrigger = true;
            if (PhysicsSystem.instance.raycast(ray, mask, maxDistance, queryTrigger)) {
                const results = PhysicsSystem.instance.raycastResults;
                results.sort((a, b) => { return a.distance > b.distance ? 1 : -1 })
                if (results.length >= 2) {
                    let offsetPos;
                    if (results[1].collider.getGroup() == Group.Weapon) {
                        offsetPos = ray.d.multiplyScalar(-0.05);
                    } else {
                        offsetPos = ray.d.multiplyScalar(-0.1);
                    }
                    this.Target.position = results[1].hitPoint.add(offsetPos);
                    if (this.Target2 && this.Target2 != results[1].collider.node) this.Target2.getComponent(Weapon).updateSprite();
                }
                if (results.length >= 2 && results[1].collider.getGroup() == Group.Weapon) {
                    this.Target2 = results[1].collider.node;
                    results[1].collider.node.getComponent(Weapon).checkUpgrade(this.Target.getComponent(WeaponPart).PartType);
                }
            }
        }
    }

    onTouchEnd(event: EventTouch) {
        if (this.Target && this.Target.getComponent(Collider).getGroup() == Group.Weapon) {
            this.Target.getComponent(Rotate).resume();
        } else if (this.Target && this.Target.getComponent(Collider).getGroup() == Group.WeaponPart) {
            let ray = new geometry.Ray();
            this.Camera3D.screenPointToRay(event.getLocationX(), event.getLocationY(), ray);
            const mask = 0xffffffff;
            const maxDistance = 10000000;
            const queryTrigger = true;
            if (PhysicsSystem.instance.raycast(ray, mask, maxDistance, queryTrigger)) {
                const results = PhysicsSystem.instance.raycastResults;
                results.sort((a, b) => { return a.distance > b.distance ? 1 : -1 })
                if (results.length >= 2 && results[1].collider.getGroup() == Group.Box && results[1].collider.node.getComponent(BoxController).IsNull) {
                    AudioManager.PlaySound(Audios.PartFall);
                    this.Target.getComponent(WeaponPart).remove();
                    this.Target.getComponent(WeaponPart).add(results[1].collider.node);
                    this.Target.position = PartPos[results[1].collider.node.name];
                    BoxManager.Instance.save();
                }
                else if (results.length >= 2 && results[1].collider.getGroup() == Group.WeaponPart &&
                    this.Target.getComponent(WeaponPart).PartType == results[1].collider.node.getComponent(WeaponPart).PartType &&
                    !this.Target.getComponent(WeaponPart).IsMax) {
                    AudioManager.PlaySound(Audios.OpenTreasureBox);
                    results[1].collider.node.getComponent(WeaponPart).upgrade();
                    this.Target.getComponent(WeaponPart).remove();
                    this.Target.destroy();
                }
                else if (results.length >= 2 && results[1].collider.getGroup() == Group.Weapon &&
                    results[1].collider.node.getComponent(Weapon).checkTarget(this.Target.getComponent(WeaponPart).PartType) != -1) {
                    AudioManager.PlaySound(Audios.OpenTreasureBox);
                    results[1].collider.node.getComponent(Weapon).upgrade(this.Target.getComponent(WeaponPart).PartType);
                    this.Target.getComponent(WeaponPart).remove();
                    this.Target.destroy();
                    BoxManager.Instance.save();
                }
                else {
                    this.Target.position = this.PartPos;
                }
            }

        }
        this.Target = null;
        if (this.Target2) this.Target2.getComponent(Weapon).updateSprite();
    }
}


